using System;
using System.Web;
using System.Web.Caching;
using CKS.EBE.Logging;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Diagnostics;

namespace CKS.EBE
{
    public class BlogSettings
    {
        private readonly object _Lock = new object();
        private static readonly Cache Cache = HttpRuntime.Cache;
        private SPWeb _CurrentWeb;
        /// <summary>
        /// cached WebProperties
        /// </summary>
        private readonly SPPropertyBag _WebProperties;

        public BlogSettings() { }

        /// <summary>
        /// always create a new BlogSettings object to be able to store WebProperties
        /// </summary>
        /// <param name="oWeb"></param>
        public BlogSettings(SPWeb oWeb)
        {
            _CurrentWeb = oWeb;
            _WebProperties = null;
        }

        /// <summary>
        /// read BlogSettings from Cache. if the cache is not available, read blogsettings and store them in the cache (with sliding expiration).
        /// this BlogSettings object is read only!
        /// </summary>
        /// <param name="url">http://www.hezser.de/blog[/default.aspx | /archive/2009/01 | /archive/2009/01/posttitle.aspx]</param>
        public BlogSettings(string url)
        {
            // change url, so it is only http://siteurl/[weburl]
            string webUrl = GetWebUrl(url);
            string blogSettingsCacheName = string.Format("EBE{0}", webUrl);

            lock (_Lock)
            {
                // try to get blogsettings for this webUrl from the cache
                var blogSettings = Cache[blogSettingsCacheName] as SPPropertyBag;
                if (blogSettings != null)
                {
                    Trace.WriteLine("Using cached BlogSettings (webUrl=" + webUrl + ")");
                }
                else
                {
                    // read blogsettings from web
                    Trace.WriteLine("Reading BlogSettings and store them in the cache (webUrl=" + webUrl + ")");
                    using (var site = new SPSite(url))
                    using (var web = site.OpenWeb())
                    {
                        var bs = new BlogSettings(web);
                        blogSettings = web.Properties;

                        int cacheTimeout = bs.PageOutputCacheTimeout;
                        Cache.Add(blogSettingsCacheName,
                                  blogSettings,
                                  null,
                                  Cache.NoAbsoluteExpiration,
                                  TimeSpan.FromMinutes(cacheTimeout),
                                  CacheItemPriority.Normal,
                                  null);
                    }
                }
                _WebProperties = blogSettings;
            }
        }

        /// <summary>
        /// change url, so it is only http://siteurl/[weburl]
        /// </summary>
        /// <param name="url">any</param>
        /// <returns>http://siteurl/[weburl]</returns>
        private static string GetWebUrl(string url)
        {
            string webUrl =url;
            if (url.Contains("/archive/"))
            {
                webUrl = url.Substring(0, url.IndexOf("/archive/"));
            }
            else if (url.Contains("/lists/"))
            {
                webUrl = url.Substring(0, url.IndexOf("/lists/"));
            }
            else if (url.EndsWith(".aspx"))
            {
                webUrl = url.Substring(0, url.LastIndexOf('/'));
            }
            else if (url.Contains("/_layouts/"))
            {
                webUrl = url.Substring(0, url.IndexOf("/_layouts"));
            }
            return webUrl;
        }

        /// <summary>
        /// Store Settings and Update Cache
        /// </summary>
        public void Update()
        {
            WebProperties.Update();

            // invalidate cached WebProperties
            string blogSettingsCacheName = string.Format("EBE{0}", _CurrentWeb.Url);
            Cache.Remove(blogSettingsCacheName);

            // update cache
            int cacheTimeout = (PageOutputCacheTimeout != 0) ? PageOutputCacheTimeout : 20;
            Cache.Add(blogSettingsCacheName,
                              WebProperties,
                              null,
                              DateTime.Now.AddMinutes(cacheTimeout),
                              Cache.NoSlidingExpiration,
                              CacheItemPriority.Normal,
                              null);
        }

        protected SPPropertyBag WebProperties
        {
            get
            {
                // return cached object
                if (_WebProperties != null) return _WebProperties;
                if (_CurrentWeb == null) _CurrentWeb = SPContext.Current.Web;
                return _CurrentWeb.Properties;
            }
        }
        
        protected string StringValue(string key)
        {
            return _WebProperties != null ? _WebProperties[key] : WebProperties[key];
        }

        protected bool BoolValue(string key)
        {
            bool bResult;

            if (_WebProperties != null)
            {
                if (bool.TryParse(_WebProperties[key], out bResult))
                    return bResult;
            }
            else
            {
                if (bool.TryParse(WebProperties[key], out bResult))
                    return bResult;
            }
            return true;
        }

        protected bool BoolValue(string key, bool bDefault)
        {
            bool bResult;

            if (_WebProperties != null)
            {
                if (bool.TryParse(_WebProperties[key], out bResult))
                    return bResult;
            }
            else
            {
                if (bool.TryParse(WebProperties[key], out bResult))
                    return bResult;
            }
            return bDefault;
        }

        protected int IntValue(string key)
        {
            int iResult;

            if (_WebProperties != null)
            {
                if (int.TryParse(_WebProperties[key], out iResult))
                    return iResult;
            }
            else
            {
                if (int.TryParse(WebProperties[key], out iResult))
                    return iResult;
            }

            return 0;
        }

        public bool CachingEnabled
        {
            get { return BoolValue("_cksBlogCachingEnabled");}
            set { WebProperties["_cksBlogCachingEnabled"] = value.ToString(); }
        }

        public bool PingbacksEnabled
        {
            get { return BoolValue("_cksBlogPingbacksEnabled"); }
            set { WebProperties["_cksBlogPingbacksEnabled"] = value.ToString(); }
        }

        public bool TrackbackReceiptEnabled
        {
            get { return BoolValue("_cksBlogTrackbackReceiptDisabled"); }
            set { WebProperties["_cksBlogTrackbackReceiptDisabled"] = value.ToString(); }
        }

        public bool DisableSelfTrackbacks
        {
            get { return BoolValue("_cksBlogDisableSelfTrackbacks"); }
            set { WebProperties["_cksBlogDisableSelfTrackbacks"] = value.ToString(); }
        }

        public bool MtfEnabled
        {
            get { return BoolValue("_cksBlogMtfEnabled"); }
            set { WebProperties["_cksBlogMtfEnabled"] = value.ToString(); }
        }

        public bool XslCacheDependencyDisabled
        {
            get { return BoolValue("_cksXslCacheDependencyDisabled"); }
            set { WebProperties["_cksXslCacheDependencyDisabled"] = value.ToString(); }
        }

        /// <summary>
        /// Cache duration in minutes. If nothing is specified, the default value is 2
        /// </summary>
        public int PageOutputCacheTimeout
        {
            [DebuggerStepThrough]
            get
            {
                var timeout = IntValue("_cksBlogPageOutputCacheTimeout");
                return (timeout != 0) ? timeout : 2;
            }
            set { WebProperties["_cksBlogPageOutputCacheTimeout"] = value.ToString(); }
        }

        public bool ThemeWikiPages
        {
            get { return BoolValue("_cksThemeWikiPages", false); }
            set { WebProperties["_cksThemeWikiPages"] = value.ToString(); }
        }

        public bool ThemeAllAspxPages
        {
            get { return BoolValue("_cksThemeAllAspxPages", false); }
            set { WebProperties["_cksThemeAllAspxPages"] = value.ToString(); }
        }

        public bool UseSiteCollectionThemes
        {
            get { return BoolValue("_cksUseSiteCollectionThemes",false); }
            set { WebProperties["_cksUseSiteCollectionThemes"] = value.ToString(); }
        }

        public string PageOutputCacheVaryByParam
        {
            get { return StringValue("_cksBlogPageOutputCacheVaryByParam"); }
            set { WebProperties["_cksBlogPageOutputCacheVaryByParam"] = value; }
        }

        public bool BlogExtensionsEnabled
        {
            get { return BoolValue("_cksBlogExtensionsEnabled"); }
            set { WebProperties["_cksBlogExtensionsEnabled"] = value.ToString(); }
        }

        public bool DeleteSpamComments
        {
            get { return BoolValue("_cksBlogDeleteSpamComments"); }
            set { WebProperties["_cksBlogDeleteSpamComments"] = value.ToString(); }
        }

        public bool DisableConvertClientDates
        {
            get { return BoolValue("_cksBlogPreventConvertClientDates"); }
            set { WebProperties["_cksBlogPreventConvertClientDates"] = value.ToString(); }
        }

        public bool EnableCaptchaComments
        {
            get { return BoolValue("_cksBlogEnableCaptchaComments"); }
            set { WebProperties["_cksBlogEnableCaptchaComments"] = value.ToString(); }
        }

        public bool TrimPostBodyOnLists 
        {
            get { return BoolValue("_cksBlogTrimPostBodyOnLists"); }
            set { WebProperties["_cksBlogTrimPostBodyOnLists"] = value.ToString(); }
        }

        public bool TrimPostBodyOnRss
        {
            get { return BoolValue("_cksBlogTrimPostBodyOnRss"); }
            set { WebProperties["_cksBlogTrimPostBodyOnRss"] = value.ToString(); }
        }

        public string AkismetKey
        {
            get { return StringValue("_cksAkismetKey"); }
            set { WebProperties["_cksAkismetKey"] = value; }
        }

        public string HomePage
        {
            get { return (string.IsNullOrEmpty(StringValue("_cksHomePage"))) ? "home.aspx" : StringValue("_cksHomePage"); }
            set { WebProperties["_cksHomePage"] = value; }
        }

        public string ProxyPort
        {
            get { return StringValue("_cksProxyPort"); }
            set { WebProperties["_cksProxyPort"] = value; }
        }
        
        public string ProxyUrl
        {
            get { return StringValue("_cksProxyUrl"); }
            set { WebProperties["_cksProxyUrl3"] = value; }
        }

        public string BlogThemeVariation
        {
            get { return StringValue("_cksBlogThemeVariation"); }
            set { WebProperties["_cksBlogThemeVariation"] = value; }
        }

        public string BlogTheme
        {
            get { return StringValue("_cksBlogTheme"); }
            set { WebProperties["_cksBlogTheme"] = value; }
        }

        public string BlogTransformParameter1
        {
            get { return StringValue("_cksBlogTransformParameter1"); }
            set { WebProperties["_cksBlogTransformParameter1"] = value; }
        }

        public string BlogTransformParameter2
        {
            get { return StringValue("_cksBlogTransformParameter2"); }
            set { WebProperties["_cksBlogTransformParameter2"] = value; }
        }

        public string BlogTransformParameter3
        {
            get { return StringValue("_cksBlogTransformParameter3"); }
            set { WebProperties["_cksBlogTransformParameter3"] = value; }
        }

        public string CustomRSSFeedUrl
        {
            get { return StringValue("_cksBlogCustomRSSFeedUrl"); }
            set { WebProperties["_cksBlogCustomRSSFeedUrl"] = value; }
        }
        
        public bool SecureSystemPages
        {
            get { return BoolValue("_cksSecureSystemPages"); }
            set { WebProperties["_cksSecureSystemPages"] = value.ToString(); }
        }

        public bool RedirectPostAspx
        {
            get { return BoolValue("_cksRedirectPostAspx"); }
            set { WebProperties["_cksRedirectPostAspx"] = value.ToString(); }
        }

        public bool ThemeSelectorEnabled
        {
            get { return BoolValue("_cksThemeSelectorEnabled"); }
            set { WebProperties["_cksThemeSelectorEnabled"] = value.ToString(); }
        }

        public string ContactEmail
        {
            get { return StringValue("_cksBlogContactEmail"); }
            set { WebProperties["_cksBlogContactEmail"] = value; }
        }

        public string RssItemCount
        {
            get { return StringValue("_cksBlogRssItemCount"); }
            set { WebProperties["_cksBlogRssItemCount"] = value; }
        }

        public bool AutoApproveComments
        {
            get { return BoolValue("_cksBlogAutoApproveComments"); }
            set { WebProperties["_cksBlogAutoApproveComments"] = value.ToString(); }
        }

        public bool TechnoratiLinks
        {
            get { return BoolValue("_cksTechnoratiLinks"); }
            set { WebProperties["_cksTechnoratiLinks"] = value.ToString(); }
        }

        public string PDFExportLicenseKey
        {
            get { return StringValue("_cksPDFExportLicenseKey"); }
            set { WebProperties["_cksPDFExportLicenseKey"] = value; }
        }

        /// <summary>
        /// cache Items.Xml and whateever data is used frequently
        /// </summary>
        public bool CacheListItemData
        {
            get { return BoolValue("_cksCacheListItemData", false); }
            set { WebProperties["_cksCacheListItemData"] = value.ToString(); }
        }

		  public int LoggingLevel
		  {
			  get { return IntValue("_cksLoggingLevel"); }
			  set { WebProperties["_cksLoggingLevel"] = value.ToString(); }
		  }

    }
}
